package com.jianyi.system.controller;

import com.jianyi.common.Constants;
import com.jianyi.common.SysLogAnnotation;
import com.jianyi.system.model.entity.SysLog;
import com.jianyi.system.model.entity.SysUser;
import com.jianyi.system.service.log.SysLogService;
import com.jianyi.system.service.user.UserService;
import com.jianyi.system.utils.VerifyCodeUtils;
import com.jianyi.system.utils.vcode.Captcha;
import com.jianyi.system.utils.vcode.GifCaptcha;
import com.jianyi.system.utils.vcode.SpecCaptcha;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class TestController {
    ;
    @Autowired
    private UserService userService;
    @Autowired
    private SysLogService sysLogService;

    /**
     * 获取验证码
     * @param response
     */
    @RequestMapping(value="getVCode",method= RequestMethod.GET)
    public void getVCode(HttpServletResponse response,HttpServletRequest request){
        try {
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            response.setContentType("image/jpg");

            //生成随机字串
            String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
            //存入Shiro会话session
            request.getSession().setAttribute(VerifyCodeUtils.V_CODE, verifyCode.toLowerCase());
            //生成图片
            int w = 146, h = 33;
            VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode);
        } catch (Exception e) {
            System.out.println("获取验证码异常："+e.getMessage());
        }
    }
    /**
     * 获取验证码（Gif版本）
     * @param response
     */
    @RequestMapping("/getGifCode")
    public void getGifCode(HttpServletResponse response, HttpServletRequest request){
        try {
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            response.setContentType("image/gif");
            /**
             * gif格式动画验证码
             * 宽，高，位数。
             */
            Captcha captcha = new GifCaptcha(146,42,4);
            //输出
            ServletOutputStream out = response.getOutputStream();
            captcha.out(out);
            out.flush();
            //存入Shiro会话session
            System.out.println( captcha.text().toLowerCase());
            request.getSession().setAttribute(VerifyCodeUtils.V_CODE, captcha.text().toLowerCase());
        } catch (Exception e) {
            System.out.println("获取验证码异常："+e.getMessage());
        }
    }

    /**
     * 获取验证码（jpg版本）
     * @param response
     */
    @RequestMapping(value="getJPGCode",method=RequestMethod.GET)
    public void getJPGCode(HttpServletResponse response,HttpServletRequest request){
        try {
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            response.setContentType("image/jpg");
            /**
             * jgp格式验证码
             * 宽，高，位数。
             */
            Captcha captcha = new SpecCaptcha(146,33,4);
            //输出
            captcha.out(response.getOutputStream());
            HttpSession session = request.getSession(true);
            //存入Session
            session.setAttribute("_code",captcha.text().toLowerCase());
        } catch (Exception e) {
            System.out.println("获取验证码异常："+e.getMessage());
        }
    }

    @RequestMapping("/test")
    @SysLogAnnotation("test测试")
    public ModelAndView test(SysUser user, String rememberMe, ModelAndView modelAndView) {
        String error = null;
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), user.getPassword());

        if ("true".equals(rememberMe)) {
            token.setRememberMe(true);
        }
        try {
            subject.login(token);

            subject.getSession().setAttribute(Constants.SESSION_KEY_USER, userService.findUser(user.getUserName()));
        } catch (UnknownAccountException e) {
            error = "用户名/密码错误";
        } catch (IncorrectCredentialsException e) {
            error = "用户名/密码错误";
        } catch (ExcessiveAttemptsException e) {
            // TODO: handle exception
            error = "登录失败多次，账户锁定10分钟";
        } catch (AuthenticationException e) {
            // 其他错误，比如锁定，如果想单独处理请单独catch处理
            e.printStackTrace();
            error = "其他错误：" + e.getMessage();
        }
        if (error != null) {// 出错了，返回登录页面
            modelAndView.addObject("message", error);
            modelAndView.setViewName("fail");
        } else {// 登录成功
            modelAndView.setViewName("success");
        }
        return modelAndView;
    }

    @RequestMapping("/logout")
    @SysLogAnnotation("logout测试")
    public ModelAndView logout(ModelAndView modelAndView) {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        modelAndView.setViewName("success");

        return modelAndView;
    }

    @RequestMapping("/get")
    @SysLogAnnotation("get测试")
    public ModelAndView getUsr() {
        ModelAndView modelAndView = new ModelAndView();
        SysUser sysUser = userService.customMethod();
        List<SysUser> ttest = userService.ttest();
        modelAndView.addObject("users", ttest);
        modelAndView.setViewName("user");
        return modelAndView;
    }

    @RequestMapping("/getlogPage")
    @SysLogAnnotation("getlogPage测试")
    public ModelAndView getLogPage() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("syslog");
        return modelAndView;
    }
    @RequestMapping("/getlog")
    @SysLogAnnotation("getlog测试")
    public Map<String, Object>  getLog(@RequestParam(value = "page", required = false) int page,
                                       @RequestParam(value = "rows", required = false) int rows,
                                       String operation) {

        Page<SysLog> all = sysLogService.findAll(operation, PageRequest.of(page-1, rows,new Sort(Sort.Direction.DESC, "id")));

        Map<String, Object> result = new HashMap<>();
        result.put("rows", all.getContent());
        result.put("total", all.getTotalElements());
        return result;
    }
    @RequestMapping("/logModifyPage")
    @SysLogAnnotation("logModifyPage测试")
    public ModelAndView logModifyPage(long logId) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("logModify");
        modelAndView.addObject("logId", logId);
        return modelAndView;
    }
    @RequestMapping("/logModify")

    @SysLogAnnotation("logModify测试")
    public ModelAndView logModify(long logId) {
        SysLog sysLog = sysLogService.get(logId).get();
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("logModify");
        modelAndView.addObject("sysLog", sysLog);
        return modelAndView;
    }

    @RequestMapping("/admin")
    @SysLogAnnotation("admin测试")
    public ModelAndView admin() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("admin");
        return modelAndView;
    }

    @RequestMapping("/fail")
    @SysLogAnnotation("fail测试")
    public ModelAndView fail() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("fail");
        return modelAndView;
    }


}
